package by.ad;

import static com.google.common.base.Charsets.UTF_8;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class HttpUtils 
{
  // HTTP header fields
  public static final String DATE = "Date".intern();
  public static final String EXPIRES = "Expires".intern();
  public static final String REFERER = "Referer".intern();
  public static final String USER_AGENT = "User-Agent".intern();
  public static final String X_FORWARDED_FOR = "X-Forwarded-For".intern();
  public static final String X_FRAME_OPTIONS = "X-Frame-Options".intern();
  public static final String REMOTE_ADDR = "Remote-Addr".intern();
  public static final String CACHE_CONTROL = "Cache-Control".intern();
  public static final String CONTENT_TYPE = "Content-Type".intern();
  public static final String LOCATION = "Location".intern();
  
  public static final String TEXT_HTML = "text/html".intern();
  public static final String TEXT_XML = "text/xml".intern();
  
  // DateFormat for http date header 
  @SuppressWarnings("serial")
  public static final class HttpDateHeaderFormat extends SimpleDateFormat {
    // HTTP Date header
    public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss 'GMT'".intern();
    
    public HttpDateHeaderFormat() {
      super(PATTERN_RFC1123, Locale.US);
      setTimeZone(TimeZone.getTimeZone("GMT"));
    }
    
    public String toString() {
      return format(new Date());
    }
    
    public static String getValue() {
      return new HttpDateHeaderFormat().toString();
    }
  }
  
  // new version of getParameterMap with warning suppression 
  @SuppressWarnings("unchecked")
  public static Map<String, String[]> getParameterMap(final ServletRequest req) {
    return req.getParameterMap();
  }
  
  // find cookie value
  public static String getCookieValue(final Cookie[] cookies, 
    final String cookieName)
  {
    if (cookies == null)
      return null;
    
    for(final Cookie c : cookies)
      if (cookieName.equalsIgnoreCase(c.getName()))
        return c.getValue();
    
    return null;
  }

  // check cookie value
  public static Boolean checkCookieValue(final HttpServletRequest req,
    final String name, final String value)
  {
    return value.equalsIgnoreCase(getCookieValue(req.getCookies(), name));
  }
  
  public static Boolean isHTTP11(final ServletRequest req)
  {
    return "HTTP/1.1".equalsIgnoreCase(req.getProtocol());
  }
    
  /* 302/303/307 redirects
   * http://habrahabr.ru/blogs/webstandards/86258/#habracut
   * http://sebastians-pamphlets.com/the-anatomy-of-http-redirects-301-302-307/
   * http://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2_%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D1%8F_HTTP
   */ 
  public static void sendRedirect(final HttpServletRequest req, 
    final HttpServletResponse resp, final String uri) 
      throws IOException
  {
    final Boolean verbGet = "GET".equalsIgnoreCase(req.getMethod());
    final Boolean verbHead = "HEAD".equalsIgnoreCase(req.getMethod());
    resp.setStatus(isHTTP11(req) 
      ? ((verbGet || verbHead) 
        ? HttpServletResponse.SC_TEMPORARY_REDIRECT
        : HttpServletResponse.SC_SEE_OTHER) 
      : (HttpServletResponse.SC_MOVED_TEMPORARILY));
    resp.setHeader(LOCATION, uri);
    
    if (!verbHead) {
      resp.setCharacterEncoding(UTF_8.name());
      resp.setContentType(TEXT_HTML);
      
      final String content = "<HTML><HEAD>"
        + "<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">"
        // + "<noscript><meta http-equiv=\"refresh\" content=\"0; url='" + uri + "'\"></noscript>"
        + "<TITLE>Moved</TITLE></HEAD><BODY" 
        // + " onload=\"location.replace(" + uri + ");\"
        + "><H1>Moved</H1>"
        + "The document has moved"
        + "<A HREF=\"" + uri + "\">here</A>."
        + "</BODY></HTML>";

        // from google
        //<HTML><HEAD> 
        //<meta http-equiv="content-type" content="text/html;charset=utf-8"> 
        //<TITLE>Redirecting</TITLE> 
        //<META HTTP-EQUIV="refresh" content="1; url=http://gitwrite.com/"> 
        //</HEAD> 
        //<BODY onLoad="location.replace('http://gitwrite.com/'+document.location.hash)"> 
        //Redirecting you to http://gitwrite.com/</BODY></HTML>
      
      resp.getWriter().write(content);
    }
  }
  
}
